package com.sdy.hospitalguard.biz.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sdy.common.model.BizException;
import com.sdy.common.model.FileObj;
import com.sdy.common.utils.Assert;
import com.sdy.hospitalguard.biz.constants.RedisConstants;
import com.sdy.hospitalguard.biz.dto.*;
import com.sdy.hospitalguard.biz.mapper.NoticeMapper;
import com.sdy.hospitalguard.biz.model.*;
import com.sdy.hospitalguard.biz.service.*;
import com.sdy.mvc.service.impl.BaseServiceImpl;
import com.sdy.redis.service.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * <p>
 * 消息通知 服务实现类
 * </p>
 *
 * @author zzq
 * @since 2020-05-09
 */
@Slf4j
@Service
public class NoticeServiceImpl extends BaseServiceImpl<Notice> implements NoticeService {
    @Autowired
    private NoticeMapper noticeMapper;
    @Autowired
    private NoticeService noticeService;
    @Autowired
    private EscortAssociatedService escortAssociatedService;
    @Autowired
    private VisitAppointmentService visitAppointmentService;
    @Autowired
    private HospitalUserService hospitalUserService;
    @Autowired
    private QrcodeService qrcodeService;
    @Autowired
    private PatientInformationService patientInformationService;
    @Autowired
    private BuildingService buildingService;
    @Autowired
    private MatchingPeopleService matchingPeopleService;
    @Autowired
    private RegulationsService regulationsService;
    @Autowired
    private RedisService redisService;


    @Override
    public List<Notice> listMyNoticeNew(Integer userId) {
        return noticeMapper.listMyNoticeNew(userId);
    }

    @Override
    public List<Notice> listMyNoticeALL(Integer userId) {
        List<Notice> list = noticeService.list(Wrappers.<Notice>lambdaQuery()
                .eq(Notice::getHandlerId, userId).orderByDesc(Notice::getCreateTime));
        noticeService.update(Wrappers.<Notice>lambdaUpdate()
                .eq(Notice::getHandlerId, userId).eq(Notice::getState, 1).set(Notice::getState, 2));
        return list;
    }

    @Override
    public Page<NoticeDto> pageMyNoticeALL(Page page, Integer userId) {
        return noticeMapper.pageMyNoticeALL(page, userId);
    }

    @Override
    public Page<Notice> pageMyALLSendNotice(Page page, Integer userId) {
        return noticeMapper.pageMyALLSendNotice(page, userId);
    }

    @Override
    public Boolean updateNoticeData(UpdateNoticeDataDTO updateNoticeDataDTO) throws BizException {
        Date date = new Date();
        Integer id = updateNoticeDataDTO.getId();
        Integer result = updateNoticeDataDTO.getResult();
        Notice notice = updateNoticeDataDTO.getNotice();
        boolean update = updateById(new Notice().setId(id).setResult(result)
                .setReason(updateNoticeDataDTO.getReason()).setHandlerTime(date)
                .setDisposeType(updateNoticeDataDTO.getDisposeType()));
        // 处理关联表数据
        Assert.isNull(notice.getType(), "消息类型出现错误!");
        Assert.isNull(notice.getAssociationId(), "关联数据出现问题!");
        boolean updateAssociaTable = false;
        // 处理陪护申请
        if (notice.getType() == 1) {
            // 陪护申请数据
            EscortAssociated one = escortAssociatedService.getOne(Wrappers.<EscortAssociated>lambdaQuery()
                    .eq(EscortAssociated::getId, notice.getAssociationId()));
            // 陪护id
            Integer userId = one.getUserId();
            Assert.isNull(one, "关联的陪护表数据缺失!");
            Integer patientId = one.getPatientId();
            Assert.isNull(patientId, "陪护表缺失患者id");
            // 查询正在陪护人数
            List<EscortAssociated> list = escortAssociatedService.list(Wrappers.<EscortAssociated>lambdaQuery()
                    .eq(EscortAssociated::getPatientId, patientId)
                    .eq(EscortAssociated::getAttendantState, 0)
                    .eq(EscortAssociated::getFlowState, 0));
            // 查询申请陪护的人是不是正在陪护别人
            EscortAssociated escortAssociated = escortAssociatedService.getOne(Wrappers.<EscortAssociated>lambdaQuery()
                    .eq(EscortAssociated::getUserId, userId)
                    .eq(EscortAssociated::getAttendantState, 0)
                    .eq(EscortAssociated::getFlowState, 0));
            Assert.notNull(escortAssociated, "该人员正在陪护其他患者,无法关联!");
            // 查询陪护规则
            Integer escortAssociatedCounts = Integer.valueOf(regulationsService.getEscortAssociatedCounts());
            // 如果正在陪护人数已达上限，则提示
            Assert.isTrue(result == 2 && list.size() >= escortAssociatedCounts, "该患者陪护人数已达上限!");
            // 审批陪护关联表数据
            updateAssociaTable = escortAssociatedService.update(Wrappers.<EscortAssociated>lambdaUpdate()
                    .eq(EscortAssociated::getId, notice.getAssociationId())
                    .set(EscortAssociated::getStartTime, result == 2 ? date : null)
                    .set(EscortAssociated::getAttendantState, (result == 1 ? 1 : 0))
                    // 如果正在陪护，则转变成待陪护状态
                    .set(EscortAssociated::getFlowState, (result == 1 ? 4 : (list.size() < escortAssociatedCounts ? 0 : 1))));
            // 如果同意并且满足规则才有必要处理下面数据
            if (result == 2 && list.size() < escortAssociatedCounts) {
                // 通行码生效(待补充)


                // 查询陪护的基本数据
                HospitalUser byId = hospitalUserService.getById(one.getUserId());
                Assert.isNull(byId, "无此用户!");
                // redis获取头像上传地址
                String path = null;
                if (StringUtils.isNotBlank(byId.getHeadPortrait())) {
                    FileObj fileObj = redisService.get(RedisConstants.FILE_UPLOAD_UUID + byId.getHeadPortrait(), FileObj.class);
                    path = fileObj.getPath();
                }
                // 查询二维码数据
                Qrcode qrcode = qrcodeService.getOne(Wrappers.<Qrcode>lambdaQuery()
                        .eq(Qrcode::getUserId, byId.getId()));
                // 查询是哪栋楼的患者
                String floorId = patientInformationService.getById(one.getPatientId()).getFloorId();
                Building building = buildingService.getById(floorId);
                Assert.isNull(building, "请确认正确的楼信息!");
                // 成为陪护时则数据同步到matchingPeople
                MatchingPeople matchingPeople = new MatchingPeople()
                        .setUserId(one.getUserId())
                        .setName(byId.getName())
                        .setCardId(byId.getIdCard())
                        .setFaceId(byId.getId())
                        .setPhotoPath(path)
                        .setQrcodeContent(qrcode.getQrcodeContent())
                        .setRemark("陪护")
                        .setBuilding(floorId)
                        .setLastChange(System.currentTimeMillis() / 1000 + "")
                        .setStatus(0);
                boolean add = matchingPeopleService.add(matchingPeople);
                Assert.notTrue(add, "matchingPeople新增陪护数据失败!");
            }
            // 处理探视申请
        } else if (notice.getType() == 2) {
            updateAssociaTable = visitAppointmentService.update(Wrappers.<VisitAppointment>lambdaUpdate()
                    .eq(VisitAppointment::getId, notice.getAssociationId())
                    .set(VisitAppointment::getAppointmentState, (result == 1 ? 1 : 0))
                    .set(VisitAppointment::getVisitState, result == 1 ? 5 : 0));

            // 如果同意前来探视
            if (result == 2) {
                // 通行码生效(待补充)


                VisitAppointment one = visitAppointmentService.getOne(Wrappers.<VisitAppointment>lambdaQuery()
                        .eq(VisitAppointment::getId, notice.getAssociationId()));
                Integer userId = one.getUserId();
                Assert.isNull(userId, "探视申请表缺失探视者数据!");
                // hospitalUser数据
                HospitalUser byId = hospitalUserService.getById(userId);
                Assert.isNull(byId, "无此用户数据!");
                // redis获取头像上传地址
                String path = null;
                if (StringUtils.isNotBlank(byId.getHeadPortrait())) {
                    FileObj fileObj = redisService.get(RedisConstants.FILE_UPLOAD_UUID + byId.getHeadPortrait(), FileObj.class);
                    path = fileObj.getPath();
                }
                // 查询二维码数据
                Qrcode qrcode = qrcodeService.getOne(Wrappers.<Qrcode>lambdaQuery()
                        .eq(Qrcode::getUserId, byId.getId()));
                // 查询是哪栋楼的患者
                String floorId = patientInformationService.getById(one.getPatientId()).getFloorId();
                Building building = buildingService.getById(floorId);
                Assert.isNull(building, "请确认正确的楼信息!");
                // 获取探视时间戳
                Date visitStartTime = one.getVisitStartTime();
                Date visitEndTime = one.getVisitEndTime();
                MatchingPeople matchingPeople = new MatchingPeople()
                        .setUserId(one.getUserId())
                        .setName(byId.getName())
                        .setCardId(byId.getIdCard())
                        .setTimeTemplate(visitStartTime.getTime() / 1000 + "-" + visitEndTime.getTime() / 1000)
                        .setFaceId(byId.getId())
                        .setPhotoPath(path)
                        .setQrcodeContent(qrcode.getQrcodeContent())
                        .setRemark("探视")
                        .setBuilding(floorId)
                        .setLastChange(System.currentTimeMillis() / 1000 + "")
                        .setStatus(0);
                System.out.println(matchingPeople);
                boolean add = matchingPeopleService.add(matchingPeople);
                Assert.notTrue(add, "matchingPeople新增陪护数据失败!");
            }
        }
        Assert.notTrue(update && updateAssociaTable, "操作失败!");
        return true;
    }

    @Override
    public Page<Notice> visitApply(Integer dispose, String content, Page page) {
        return null;
    }


    /**
     * PC端 接口
     */

    @Override
    public Page<BacklogVisitApplyDTO> backlogVisitApply(Page page,Integer arreaId) {
        return noticeMapper.backlogVisitApply(page,arreaId);
    }

    @Override
    public Page<BacklogVisitApplyPageDTO> backlogVisitApplyPage(Page page, String condition, Integer type,Integer arreaId) {
        return noticeMapper.backlogVisitApplyPage(page, condition, type,arreaId);
    }

    @Override
    public List<BacklogVisitApplyPageDTO> backlogVisitApplyExcel(String condition, Integer result,Integer arreaId) {
        return noticeMapper.backlogVisitApplyPage(condition, result,arreaId);
    }

    @Override
    public Page<BacklogEscorApplyDTO> backlogEscortApply(Page page,Integer arreaId) {
        return noticeMapper.backlogEscortApply(page,arreaId);
    }

    @Override
    public Page<BacklogEscorApplyPageDTO> backlogEscortApplyPage(Page page, String condition, Integer result,Integer arreaId) {
        return noticeMapper.backlogEscortApplyPage(page, condition, result,arreaId);
    }

    @Override
    public List<BacklogEscorApplyPageDTO> backlogEscortApplyExcel(String condition, Integer result,Integer arreaId) {
        return noticeMapper.backlogEscortApplyPage(condition, result,arreaId);
    }

    @Override
    public Page<WardTodayVisitDTO> wardTodayVisit(Page page) {
        return noticeMapper.wardTodayVisit(page);
    }

}
